home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / trace.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2005-10-18  |  22KB  |  716 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. """program/module to trace Python program or function execution
  5.  
  6. Sample use, command line:
  7.   trace.py -c -f counts --ignore-dir '$prefix' spam.py eggs
  8.   trace.py -t --ignore-dir '$prefix' spam.py eggs
  9.   trace.py --trackcalls spam.py eggs
  10.  
  11. Sample use, programmatically
  12.    # create a Trace object, telling it what to ignore, and whether to
  13.    # do tracing or line-counting or both.
  14.    trace = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix,], trace=0,
  15.                        count=1)
  16.    # run the new command using the given trace
  17.    trace.run('main()')
  18.    # make a report, telling it where you want output
  19.    r = trace.results()
  20.    r.write_results(show_missing=True)
  21. """
  22. import linecache
  23. import os
  24. import re
  25. import sys
  26. import threading
  27. import token
  28. import tokenize
  29. import types
  30. import gc
  31.  
  32. try:
  33.     import cPickle
  34.     pickle = cPickle
  35. except ImportError:
  36.     import pickle
  37.  
  38.  
  39. def usage(outfile):
  40.     outfile.write("Usage: %s [OPTIONS] <file> [ARGS]\n\nMeta-options:\n--help                Display this help then exit.\n--version             Output version information then exit.\n\nOtherwise, exactly one of the following three options must be given:\n-t, --trace           Print each line to sys.stdout before it is executed.\n-c, --count           Count the number of times each line is executed\n                      and write the counts to <module>.cover for each\n                      module executed, in the module's directory.\n                      See also `--coverdir', `--file', `--no-report' below.\n-l, --listfuncs       Keep track of which functions are executed at least\n                      once and write the results to sys.stdout after the\n                      program exits.\n-T, --trackcalls      Keep track of caller/called pairs and write the\n                      results to sys.stdout after the program exits.\n-r, --report          Generate a report from a counts file; do not execute\n                      any code.  `--file' must specify the results file to\n                      read, which must have been created in a previous run\n                      with `--count --file=FILE'.\n\nModifiers:\n-f, --file=<file>     File to accumulate counts over several runs.\n-R, --no-report       Do not generate the coverage report files.\n                      Useful if you want to accumulate over several runs.\n-C, --coverdir=<dir>  Directory where the report files.  The coverage\n                      report for <package>.<module> is written to file\n                      <dir>/<package>/<module>.cover.\n-m, --missing         Annotate executable lines that were not executed\n                      with '>>>>>> '.\n-s, --summary         Write a brief summary on stdout for each file.\n                      (Can only be used with --count or --report.)\n\nFilters, may be repeated multiple times:\n--ignore-module=<mod> Ignore the given module and its submodules\n                      (if it is a package).\n--ignore-dir=<dir>    Ignore files in the given directory (multiple\n                      directories can be joined by os.pathsep).\n" % sys.argv[0])
  41.  
  42. PRAGMA_NOCOVER = '#pragma NO COVER'
  43. rx_blank = re.compile('^\\s*(#.*)?$')
  44.  
  45. class Ignore:
  46.     
  47.     def __init__(self, modules = None, dirs = None):
  48.         if not modules:
  49.             pass
  50.         self._mods = []
  51.         if not dirs:
  52.             pass
  53.         self._dirs = []
  54.         self._dirs = map(os.path.normpath, self._dirs)
  55.         self._ignore = {
  56.             '<string>': 1 }
  57.  
  58.     
  59.     def names(self, filename, modulename):
  60.         if self._ignore.has_key(modulename):
  61.             return self._ignore[modulename]
  62.         
  63.         for mod in self._mods:
  64.             if mod == modulename:
  65.                 self._ignore[modulename] = 1
  66.                 return 1
  67.             
  68.             n = len(mod)
  69.             if mod == modulename[:n] and modulename[n] == '.':
  70.                 self._ignore[modulename] = 1
  71.                 return 1
  72.                 continue
  73.         
  74.         if filename is None:
  75.             self._ignore[modulename] = 1
  76.             return 1
  77.         
  78.         for d in self._dirs:
  79.             if filename.startswith(d + os.sep):
  80.                 self._ignore[modulename] = 1
  81.                 return 1
  82.                 continue
  83.         
  84.         self._ignore[modulename] = 0
  85.         return 0
  86.  
  87.  
  88.  
  89. def modname(path):
  90.     '''Return a plausible module name for the patch.'''
  91.     base = os.path.basename(path)
  92.     (filename, ext) = os.path.splitext(base)
  93.     return filename
  94.  
  95.  
  96. def fullmodname(path):
  97.     '''Return a plausible module name for the path.'''
  98.     longest = ''
  99.     for dir in sys.path:
  100.         if path.startswith(dir) and path[len(dir)] == os.path.sep:
  101.             if len(dir) > len(longest):
  102.                 longest = dir
  103.             
  104.         len(dir) > len(longest)
  105.     
  106.     if longest:
  107.         base = path[len(longest) + 1:]
  108.     else:
  109.         base = path
  110.     base = base.replace(os.sep, '.')
  111.     if os.altsep:
  112.         base = base.replace(os.altsep, '.')
  113.     
  114.     (filename, ext) = os.path.splitext(base)
  115.     return filename
  116.  
  117.  
  118. class CoverageResults:
  119.     
  120.     def __init__(self, counts = None, calledfuncs = None, infile = None, callers = None, outfile = None):
  121.         self.counts = counts
  122.         if self.counts is None:
  123.             self.counts = { }
  124.         
  125.         self.counter = self.counts.copy()
  126.         self.calledfuncs = calledfuncs
  127.         if self.calledfuncs is None:
  128.             self.calledfuncs = { }
  129.         
  130.         self.calledfuncs = self.calledfuncs.copy()
  131.         self.callers = callers
  132.         if self.callers is None:
  133.             self.callers = { }
  134.         
  135.         self.callers = self.callers.copy()
  136.         self.infile = infile
  137.         self.outfile = outfile
  138.         if self.infile:
  139.             
  140.             try:
  141.                 (counts, calledfuncs, callers) = pickle.load(open(self.infile, 'rb'))
  142.                 self.update(self.__class__(counts, calledfuncs, callers))
  143.             except (IOError, EOFError, ValueError):
  144.                 err = None
  145.                 print >>sys.stderr, 'Skipping counts file %r: %s' % (self.infile, err)
  146.             except:
  147.                 None<EXCEPTION MATCH>(IOError, EOFError, ValueError)
  148.             
  149.  
  150.         None<EXCEPTION MATCH>(IOError, EOFError, ValueError)
  151.  
  152.     
  153.     def update(self, other):
  154.         '''Merge in the data from another CoverageResults'''
  155.         counts = self.counts
  156.         calledfuncs = self.calledfuncs
  157.         callers = self.callers
  158.         other_counts = other.counts
  159.         other_calledfuncs = other.calledfuncs
  160.         other_callers = other.callers
  161.         for key in other_counts.keys():
  162.             counts[key] = counts.get(key, 0) + other_counts[key]
  163.         
  164.         for key in other_calledfuncs.keys():
  165.             calledfuncs[key] = 1
  166.         
  167.         for key in other_callers.keys():
  168.             callers[key] = 1
  169.         
  170.  
  171.     
  172.     def write_results(self, show_missing = True, summary = False, coverdir = None):
  173.         '''
  174.         @param coverdir
  175.         '''
  176.         if self.calledfuncs:
  177.             print 
  178.             print 'functions called:'
  179.             calls = self.calledfuncs.keys()
  180.             calls.sort()
  181.             for filename, modulename, funcname in calls:
  182.                 print 'filename: %s, modulename: %s, funcname: %s' % (filename, modulename, funcname)
  183.             
  184.         
  185.         if self.callers:
  186.             print 
  187.             print 'calling relationships:'
  188.             calls = self.callers.keys()
  189.             calls.sort()
  190.             lastfile = lastcfile = ''
  191.             for pfile, pmod, pfunc in calls:
  192.                 (cfile, cmod, cfunc) = None
  193.                 if pfile != lastfile:
  194.                     print 
  195.                     print '***', pfile, '***'
  196.                     lastfile = pfile
  197.                     lastcfile = ''
  198.                 
  199.                 if cfile != pfile and lastcfile != cfile:
  200.                     print '  -->', cfile
  201.                     lastcfile = cfile
  202.                 
  203.                 print '    %s.%s -> %s.%s' % (pmod, pfunc, cmod, cfunc)
  204.             
  205.         
  206.         per_file = { }
  207.         for filename, lineno in self.counts.keys():
  208.             lines_hit = per_file[filename] = per_file.get(filename, { })
  209.             lines_hit[lineno] = self.counts[(filename, lineno)]
  210.         
  211.         sums = { }
  212.         for filename, count in per_file.iteritems():
  213.             if filename == '<string>':
  214.                 continue
  215.             
  216.             if filename.endswith('.pyc') or filename.endswith('.pyo'):
  217.                 filename = filename[:-1]
  218.             
  219.             if coverdir is None:
  220.                 dir = os.path.dirname(os.path.abspath(filename))
  221.                 modulename = modname(filename)
  222.             else:
  223.                 dir = coverdir
  224.                 if not os.path.exists(dir):
  225.                     os.makedirs(dir)
  226.                 
  227.                 modulename = fullmodname(filename)
  228.             if show_missing:
  229.                 lnotab = find_executable_linenos(filename)
  230.             else:
  231.                 lnotab = { }
  232.             source = linecache.getlines(filename)
  233.             coverpath = os.path.join(dir, modulename + '.cover')
  234.             (n_hits, n_lines) = self.write_results_file(coverpath, source, lnotab, count)
  235.             if summary and n_lines:
  236.                 percent = int(100 * n_hits / n_lines)
  237.                 sums[modulename] = (n_lines, percent, modulename, filename)
  238.                 continue
  239.         
  240.         if summary and sums:
  241.             mods = sums.keys()
  242.             mods.sort()
  243.             print 'lines   cov%   module   (path)'
  244.             for m in mods:
  245.                 (n_lines, percent, modulename, filename) = sums[m]
  246.                 print '%5d   %3d%%   %s   (%s)' % sums[m]
  247.             
  248.         
  249.         if self.outfile:
  250.             
  251.             try:
  252.                 pickle.dump((self.counts, self.calledfuncs, self.callers), open(self.outfile, 'wb'), 1)
  253.             except IOError:
  254.                 err = None
  255.                 print >>sys.stderr, "Can't save counts files because %s" % err
  256.             except:
  257.                 None<EXCEPTION MATCH>IOError
  258.             
  259.  
  260.         None<EXCEPTION MATCH>IOError
  261.  
  262.     
  263.     def write_results_file(self, path, lines, lnotab, lines_hit):
  264.         '''Return a coverage results file in path.'''
  265.         
  266.         try:
  267.             outfile = open(path, 'w')
  268.         except IOError:
  269.             err = None
  270.             print >>sys.stderr, 'trace: Could not open %r for writing: %s- skipping' % (path, err)
  271.             return (0, 0)
  272.  
  273.         n_lines = 0
  274.         n_hits = 0
  275.         for i, line in enumerate(lines):
  276.             lineno = i + 1
  277.             if lineno in lines_hit:
  278.                 outfile.write('%5d: ' % lines_hit[lineno])
  279.                 n_hits += 1
  280.                 n_lines += 1
  281.             elif rx_blank.match(line):
  282.                 outfile.write('       ')
  283.             elif lineno in lnotab and PRAGMA_NOCOVER not in lines[i]:
  284.                 outfile.write('>>>>>> ')
  285.                 n_lines += 1
  286.             else:
  287.                 outfile.write('       ')
  288.             outfile.write(lines[i].expandtabs(8))
  289.         
  290.         outfile.close()
  291.         return (n_hits, n_lines)
  292.  
  293.  
  294.  
  295. def find_lines_from_code(code, strs):
  296.     '''Return dict where keys are lines in the line number table.'''
  297.     linenos = { }
  298.     line_increments = [ ord(c) for c in code.co_lnotab[1::2] ]
  299.     table_length = len(line_increments)
  300.     docstring = False
  301.     lineno = code.co_firstlineno
  302.     for li in line_increments:
  303.         lineno += li
  304.         if lineno not in strs:
  305.             linenos[lineno] = 1
  306.             continue
  307.         []
  308.     
  309.     return linenos
  310.  
  311.  
  312. def find_lines(code, strs):
  313.     '''Return lineno dict for all code objects reachable from code.'''
  314.     linenos = find_lines_from_code(code, strs)
  315.     for c in code.co_consts:
  316.         if isinstance(c, types.CodeType):
  317.             linenos.update(find_lines(c, strs))
  318.             continue
  319.     
  320.     return linenos
  321.  
  322.  
  323. def find_strings(filename):
  324.     '''Return a dict of possible docstring positions.
  325.  
  326.     The dict maps line numbers to strings.  There is an entry for
  327.     line that contains only a string or a part of a triple-quoted
  328.     string.
  329.     '''
  330.     d = { }
  331.     prev_ttype = token.INDENT
  332.     f = open(filename)
  333.     for ttype, tstr, start, end, line in tokenize.generate_tokens(f.readline):
  334.         if ttype == token.STRING:
  335.             if prev_ttype == token.INDENT:
  336.                 (sline, scol) = start
  337.                 (eline, ecol) = end
  338.                 for i in range(sline, eline + 1):
  339.                     d[i] = 1
  340.                 
  341.             
  342.         
  343.         prev_ttype = ttype
  344.     
  345.     f.close()
  346.     return d
  347.  
  348.  
  349. def find_executable_linenos(filename):
  350.     '''Return dict where keys are line numbers in the line number table.'''
  351.     
  352.     try:
  353.         prog = open(filename, 'rU').read()
  354.     except IOError:
  355.         err = None
  356.         print >>sys.stderr, 'Not printing coverage data for %r: %s' % (filename, err)
  357.         return { }
  358.  
  359.     code = compile(prog, filename, 'exec')
  360.     strs = find_strings(filename)
  361.     return find_lines(code, strs)
  362.  
  363.  
  364. class Trace:
  365.     
  366.     def __init__(self, count = 1, trace = 1, countfuncs = 0, countcallers = 0, ignoremods = (), ignoredirs = (), infile = None, outfile = None):
  367.         """
  368.         @param count true iff it should count number of times each
  369.                      line is executed
  370.         @param trace true iff it should print out each line that is
  371.                      being counted
  372.         @param countfuncs true iff it should just output a list of
  373.                      (filename, modulename, funcname,) for functions
  374.                      that were called at least once;  This overrides
  375.                      `count' and `trace'
  376.         @param ignoremods a list of the names of modules to ignore
  377.         @param ignoredirs a list of the names of directories to ignore
  378.                      all of the (recursive) contents of
  379.         @param infile file from which to read stored counts to be
  380.                      added into the results
  381.         @param outfile file in which to write the results
  382.         """
  383.         self.infile = infile
  384.         self.outfile = outfile
  385.         self.ignore = Ignore(ignoremods, ignoredirs)
  386.         self.counts = { }
  387.         self.blabbed = { }
  388.         self.pathtobasename = { }
  389.         self.donothing = 0
  390.         self.trace = trace
  391.         self._calledfuncs = { }
  392.         self._callers = { }
  393.         self._caller_cache = { }
  394.         if countcallers:
  395.             self.globaltrace = self.globaltrace_trackcallers
  396.         elif countfuncs:
  397.             self.globaltrace = self.globaltrace_countfuncs
  398.         elif trace and count:
  399.             self.globaltrace = self.globaltrace_lt
  400.             self.localtrace = self.localtrace_trace_and_count
  401.         elif trace:
  402.             self.globaltrace = self.globaltrace_lt
  403.             self.localtrace = self.localtrace_trace
  404.         elif count:
  405.             self.globaltrace = self.globaltrace_lt
  406.             self.localtrace = self.localtrace_count
  407.         else:
  408.             self.donothing = 1
  409.  
  410.     
  411.     def run(self, cmd):
  412.         import __main__ as __main__
  413.         dict = __main__.__dict__
  414.         if not self.donothing:
  415.             sys.settrace(self.globaltrace)
  416.             threading.settrace(self.globaltrace)
  417.         
  418.         
  419.         try:
  420.             exec cmd in dict, dict
  421.         finally:
  422.             if not self.donothing:
  423.                 sys.settrace(None)
  424.                 threading.settrace(None)
  425.             
  426.  
  427.  
  428.     
  429.     def runctx(self, cmd, globals = None, locals = None):
  430.         if globals is None:
  431.             globals = { }
  432.         
  433.         if locals is None:
  434.             locals = { }
  435.         
  436.         if not self.donothing:
  437.             sys.settrace(self.globaltrace)
  438.             threading.settrace(self.globaltrace)
  439.         
  440.         
  441.         try:
  442.             exec cmd in globals, locals
  443.         finally:
  444.             if not self.donothing:
  445.                 sys.settrace(None)
  446.                 threading.settrace(None)
  447.             
  448.  
  449.  
  450.     
  451.     def runfunc(self, func, *args, **kw):
  452.         result = None
  453.         if not self.donothing:
  454.             sys.settrace(self.globaltrace)
  455.         
  456.         
  457.         try:
  458.             result = func(*args, **kw)
  459.         finally:
  460.             if not self.donothing:
  461.                 sys.settrace(None)
  462.             
  463.  
  464.         return result
  465.  
  466.     
  467.     def file_module_function_of(self, frame):
  468.         code = frame.f_code
  469.         filename = code.co_filename
  470.         if filename:
  471.             modulename = modname(filename)
  472.         else:
  473.             modulename = None
  474.         funcname = code.co_name
  475.         clsname = None
  476.         return (filename, modulename, funcname)
  477.  
  478.     
  479.     def globaltrace_trackcallers(self, frame, why, arg):
  480.         '''Handler for call events.
  481.  
  482.         Adds information about who called who to the self._callers dict.
  483.         '''
  484.         if why == 'call':
  485.             this_func = self.file_module_function_of(frame)
  486.             parent_func = self.file_module_function_of(frame.f_back)
  487.             self._callers[(parent_func, this_func)] = 1
  488.         
  489.  
  490.     
  491.     def globaltrace_countfuncs(self, frame, why, arg):
  492.         '''Handler for call events.
  493.  
  494.         Adds (filename, modulename, funcname) to the self._calledfuncs dict.
  495.         '''
  496.         if why == 'call':
  497.             this_func = self.file_module_function_of(frame)
  498.             self._calledfuncs[this_func] = 1
  499.         
  500.  
  501.     
  502.     def globaltrace_lt(self, frame, why, arg):
  503.         """Handler for call events.
  504.  
  505.         If the code block being entered is to be ignored, returns `None',
  506.         else returns self.localtrace.
  507.         """
  508.         if why == 'call':
  509.             code = frame.f_code
  510.             filename = code.co_filename
  511.             if filename:
  512.                 modulename = modname(filename)
  513.                 if modulename is not None:
  514.                     ignore_it = self.ignore.names(filename, modulename)
  515.                     if not ignore_it:
  516.                         if self.trace:
  517.                             print ' --- modulename: %s, funcname: %s' % (modulename, code.co_name)
  518.                         
  519.                         return self.localtrace
  520.                     
  521.                 
  522.             else:
  523.                 return None
  524.         
  525.  
  526.     
  527.     def localtrace_trace_and_count(self, frame, why, arg):
  528.         if why == 'line':
  529.             filename = frame.f_code.co_filename
  530.             lineno = frame.f_lineno
  531.             key = (filename, lineno)
  532.             self.counts[key] = self.counts.get(key, 0) + 1
  533.             bname = os.path.basename(filename)
  534.             print '%s(%d): %s' % (bname, lineno, linecache.getline(filename, lineno)),
  535.         
  536.         return self.localtrace
  537.  
  538.     
  539.     def localtrace_trace(self, frame, why, arg):
  540.         if why == 'line':
  541.             filename = frame.f_code.co_filename
  542.             lineno = frame.f_lineno
  543.             bname = os.path.basename(filename)
  544.             print '%s(%d): %s' % (bname, lineno, linecache.getline(filename, lineno)),
  545.         
  546.         return self.localtrace
  547.  
  548.     
  549.     def localtrace_count(self, frame, why, arg):
  550.         if why == 'line':
  551.             filename = frame.f_code.co_filename
  552.             lineno = frame.f_lineno
  553.             key = (filename, lineno)
  554.             self.counts[key] = self.counts.get(key, 0) + 1
  555.         
  556.         return self.localtrace
  557.  
  558.     
  559.     def results(self):
  560.         return CoverageResults(self.counts, infile = self.infile, outfile = self.outfile, calledfuncs = self._calledfuncs, callers = self._callers)
  561.  
  562.  
  563.  
  564. def _err_exit(msg):
  565.     sys.stderr.write('%s: %s\n' % (sys.argv[0], msg))
  566.     sys.exit(1)
  567.  
  568.  
  569. def main(argv = None):
  570.     import getopt as getopt
  571.     if argv is None:
  572.         argv = sys.argv
  573.     
  574.     
  575.     try:
  576.         (opts, prog_argv) = getopt.getopt(argv[1:], 'tcrRf:d:msC:lT', [
  577.             'help',
  578.             'version',
  579.             'trace',
  580.             'count',
  581.             'report',
  582.             'no-report',
  583.             'summary',
  584.             'file=',
  585.             'missing',
  586.             'ignore-module=',
  587.             'ignore-dir=',
  588.             'coverdir=',
  589.             'listfuncs',
  590.             'trackcalls'])
  591.     except getopt.error:
  592.         msg = None
  593.         sys.stderr.write('%s: %s\n' % (sys.argv[0], msg))
  594.         sys.stderr.write("Try `%s --help' for more information\n" % sys.argv[0])
  595.         sys.exit(1)
  596.  
  597.     trace = 0
  598.     count = 0
  599.     report = 0
  600.     no_report = 0
  601.     counts_file = None
  602.     missing = 0
  603.     ignore_modules = []
  604.     ignore_dirs = []
  605.     coverdir = None
  606.     summary = 0
  607.     listfuncs = False
  608.     countcallers = False
  609.     for opt, val in opts:
  610.         if opt == '--help':
  611.             usage(sys.stdout)
  612.             sys.exit(0)
  613.         
  614.         if opt == '--version':
  615.             sys.stdout.write('trace 2.0\n')
  616.             sys.exit(0)
  617.         
  618.         if opt == '-T' or opt == '--trackcalls':
  619.             countcallers = True
  620.             continue
  621.         
  622.         if opt == '-l' or opt == '--listfuncs':
  623.             listfuncs = True
  624.             continue
  625.         
  626.         if opt == '-t' or opt == '--trace':
  627.             trace = 1
  628.             continue
  629.         
  630.         if opt == '-c' or opt == '--count':
  631.             count = 1
  632.             continue
  633.         
  634.         if opt == '-r' or opt == '--report':
  635.             report = 1
  636.             continue
  637.         
  638.         if opt == '-R' or opt == '--no-report':
  639.             no_report = 1
  640.             continue
  641.         
  642.         if opt == '-f' or opt == '--file':
  643.             counts_file = val
  644.             continue
  645.         
  646.         if opt == '-m' or opt == '--missing':
  647.             missing = 1
  648.             continue
  649.         
  650.         if opt == '-C' or opt == '--coverdir':
  651.             coverdir = val
  652.             continue
  653.         
  654.         if opt == '-s' or opt == '--summary':
  655.             summary = 1
  656.             continue
  657.         
  658.         if opt == '--ignore-module':
  659.             ignore_modules.append(val)
  660.             continue
  661.         
  662.         if opt == '--ignore-dir':
  663.             for s in val.split(os.pathsep):
  664.                 s = os.path.expandvars(s)
  665.                 s = s.replace('$prefix', os.path.join(sys.prefix, 'lib', 'python' + sys.version[:3]))
  666.                 s = s.replace('$exec_prefix', os.path.join(sys.exec_prefix, 'lib', 'python' + sys.version[:3]))
  667.                 s = os.path.normpath(s)
  668.                 ignore_dirs.append(s)
  669.             
  670.             continue
  671.         
  672.         if not 0:
  673.             raise AssertionError, 'Should never get here'
  674.     
  675.     if listfuncs:
  676.         if count or trace:
  677.             _err_exit('cannot specify both --listfuncs and (--trace or --count)')
  678.         
  679.     if not count and trace and report and listfuncs or countcallers:
  680.         _err_exit('must specify one of --trace, --count, --report, --listfuncs, or --trackcalls')
  681.     
  682.     if report and no_report:
  683.         _err_exit('cannot specify both --report and --no-report')
  684.     
  685.     if report and not counts_file:
  686.         _err_exit('--report requires a --file')
  687.     
  688.     if no_report and len(prog_argv) == 0:
  689.         _err_exit('missing name of file to run')
  690.     
  691.     if report:
  692.         results = CoverageResults(infile = counts_file, outfile = counts_file)
  693.         results.write_results(missing, summary = summary, coverdir = coverdir)
  694.     else:
  695.         sys.argv = prog_argv
  696.         progname = prog_argv[0]
  697.         sys.path[0] = os.path.split(progname)[0]
  698.         t = Trace(count, trace, countfuncs = listfuncs, countcallers = countcallers, ignoremods = ignore_modules, ignoredirs = ignore_dirs, infile = counts_file, outfile = counts_file)
  699.         
  700.         try:
  701.             t.run('execfile(%r)' % (progname,))
  702.         except IOError:
  703.             err = None
  704.             _err_exit('Cannot run file %r because: %s' % (sys.argv[0], err))
  705.         except SystemExit:
  706.             pass
  707.  
  708.         results = t.results()
  709.         if not no_report:
  710.             results.write_results(missing, summary = summary, coverdir = coverdir)
  711.         
  712.  
  713. if __name__ == '__main__':
  714.     main()
  715.  
  716.